home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Mail / Sources / UMailer.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  49.2 KB  |  1,712 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UMailer.cp
  3. // Copyright © 1988-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6.  
  7. #if qPowerTalk
  8.  
  9. #ifndef __UMAILER__
  10. #include "UMailer.h"
  11. #endif
  12.  
  13. // MacApp
  14.  
  15. //    #ifndef __UAPPLICATION__
  16. //    #include "UApplication.h"
  17. //    #endif
  18.  
  19. #ifndef __UDISPATCHER__
  20. #include "UDispatcher.h"
  21. #endif
  22.  
  23. #ifndef __UERRORMGR__
  24. #include "UErrorMgr.h"
  25. #endif
  26.  
  27. #ifndef __UFAILURE__
  28. #include "UFailure.h"
  29. #endif
  30.  
  31. #ifndef __UFILEBASEDDOCUMENT__
  32. #include "UFileBasedDocument.h"
  33. #endif
  34.  
  35. #ifndef __UFILE__
  36. #include "UFile.h"
  37. #endif
  38.  
  39. #ifndef __UMACAPPGLOBALS__
  40. #include "UMacAppGlobals.h"
  41. #endif
  42.  
  43. #ifndef __UMACAPPUTILITIES__
  44. #include "UMacAppUtilities.h"
  45. #endif
  46.  
  47. #ifndef __UMAILABLE__
  48. #include "UMailable.h"
  49. #endif
  50.  
  51. #ifndef __UMAILERVIEW__
  52. #include "UMailerView.h"
  53. #endif
  54.  
  55. #ifndef __UMEMORY__
  56. #include "UMemory.h"
  57. #endif
  58.  
  59. #ifndef __UMENUMGR__
  60. #include "UMenuMgr.h"
  61. #endif
  62.  
  63. #ifndef __USCRIPTING__
  64. #include "UScripting.h"
  65. #endif
  66.  
  67. #ifndef __UWINDOW__
  68. #include "UWindow.h"
  69. #endif
  70.  
  71. // Toolbox
  72.  
  73. #ifndef __AEREGISTRY__
  74. #include <AERegistry.h>
  75. #endif
  76.  
  77. #ifndef __FOLDERS__
  78. #include <Folders.h>
  79. #endif
  80.  
  81. #ifndef    __OCEERRORS__
  82. #include <OCEErrors.h>
  83. #endif
  84.  
  85. #ifndef __OCESTANDARDDIRECTORY__
  86. #include <OCEStandardDirectory.h>
  87. #endif
  88.  
  89. //========================================================================================
  90. // GLOBAL Functions
  91. //========================================================================================
  92.  
  93. SMPDrawImageUPP gMacAppImageProc;
  94.  
  95. //----------------------------------------------------------------------------------------
  96. // Prototypes for local functions
  97. //----------------------------------------------------------------------------------------
  98.  
  99. pascal void MacAppImageProc(long refcon, Boolean inColor);
  100. OCEPackedRecipient* StringToAddress(const CStr255& addressStr);
  101.  
  102. //----------------------------------------------------------------------------------------
  103. // MacAppImageProc
  104. //----------------------------------------------------------------------------------------
  105. #pragma segment AMailerRes
  106.  
  107. pascal void MacAppImageProc(long refcon,
  108.                             Boolean inColor)
  109. {
  110.     TDocument* theDocument = (TDocument *)refcon;
  111.     MMailable* mailDoc = MA_DYNAMIC_CAST(MMailable, theDocument);
  112.     if (mailDoc)
  113.         mailDoc->ImageDocumentForLetter(inColor);
  114. }
  115.  
  116. //----------------------------------------------------------------------------------------
  117. // InitUMailer
  118. //----------------------------------------------------------------------------------------
  119. #pragma segment AInit
  120.  
  121. void InitUMailer()
  122. {
  123.     if (!HasAOCEToolBox())
  124.     {
  125. #if qDebug
  126.         ProgramBreak("InitUMailer called but AOCE isn't present.");
  127. #endif
  128.         return;
  129.     }
  130.     FailNIL(gMacAppImageProc = NewSMPDrawImageProc(&MacAppImageProc));
  131.     
  132.     InitUMailerView();
  133. }
  134.  
  135. //========================================================================================
  136. // CLASS TLetter
  137. //========================================================================================
  138. #undef Inherited
  139. #define Inherited TObject
  140.  
  141. #pragma segment AOCEMailerRes
  142. MA_DEFINE_CLASS_M1(TLetter, Inherited);
  143.  
  144. //----------------------------------------------------------------------------------------
  145. // TLetter::TLetter
  146. //----------------------------------------------------------------------------------------
  147. #pragma segment ConstructorRes
  148.  
  149. TLetter::TLetter():
  150.     fMailDoc(NULL),
  151.     fDocument(NULL),
  152.     fLetterTabber(NULL),
  153.     fLetterDescriptor(NULL),
  154.     fHasMailer(FALSE),
  155.     fHasBeenSent(FALSE),
  156.     fLetterExists(FALSE),
  157.     fReplyToAll(TRUE)
  158. {
  159. }
  160.  
  161. //----------------------------------------------------------------------------------------
  162. // TLetter destructor
  163. //----------------------------------------------------------------------------------------
  164. #pragma segment MADestructorRes
  165.  
  166. TLetter::~TLetter()
  167. {
  168.     fLetterDescriptor = DisposeIfHandle(fLetterDescriptor);
  169. }
  170.  
  171. //----------------------------------------------------------------------------------------
  172. // TLetter::ILetter
  173. //----------------------------------------------------------------------------------------
  174. #pragma segment AMailerRes
  175.  
  176. void TLetter::ILetter(MMailable* mailDoc)
  177. {
  178.     IObject();
  179.     
  180.     fMailDoc = mailDoc;
  181.     fDocument = MA_DYNAMIC_CAST(TDocument, mailDoc);
  182.     FailNonObject(fDocument);
  183. }
  184.  
  185. //----------------------------------------------------------------------------------------
  186. // TLetter::AddMailer
  187. //----------------------------------------------------------------------------------------
  188. #pragma segment AMailerRes
  189.  
  190. void TLetter::AddMailer()
  191. {
  192.     CTempDesc mySpec;
  193.     fDocument->MakeObjectSpecifier(mySpec, fDocument->GetSpecifierForm());
  194.     
  195.     TAppleEvent* theEvent =  TAppleEvent::MakeCreateElementEvent(gServerAddress, kAEWaitReply, 
  196.         mySpec, cMailer, kAEBeginning, CAEDesc::fgNullDesc, CAEDesc::fgNullDesc);
  197.         
  198.     TClientCommand* theSendAECmd = new TClientCommand;
  199.     theSendAECmd->IClientCommand(cAECreateElement, gDispatcher, FALSE, FALSE,
  200.                                  gDispatcher, theEvent);
  201.     
  202.     gDispatcher->PostCommand(theSendAECmd);
  203. }
  204.  
  205. //----------------------------------------------------------------------------------------
  206. // TLetter::AddNativeMailContent
  207. //----------------------------------------------------------------------------------------
  208. #pragma segment AMailerRes
  209.  
  210. void TLetter::AddNativeMailContent(Boolean& /*okToSend*/)
  211. {
  212.     // Override to add your document content in its own format. 
  213. }
  214.  
  215. //----------------------------------------------------------------------------------------
  216. // TLetter::AddSnapshotMailContent
  217. //----------------------------------------------------------------------------------------
  218. #pragma segment AMailerRes
  219.  
  220. void TLetter::AddSnapshotMailContent(Boolean& /*okToSend*/)
  221. {
  222.     // Default implementation takes a snapshot of the mailer window. 
  223.     
  224.     FailOSErr(SMPImage((WindowPtr)GetMailerWindowRef(), gMacAppImageProc, (long)fDocument, TRUE));
  225. }
  226.  
  227. //----------------------------------------------------------------------------------------
  228. // TLetter::AddStandardMailContent
  229. //----------------------------------------------------------------------------------------
  230. #pragma segment AMailerRes
  231.  
  232. void TLetter::AddStandardMailContent(Boolean& /*okToSend*/)
  233. {
  234.     // Override to add your document content in standard mail format. 
  235. }
  236.  
  237. //----------------------------------------------------------------------------------------
  238. // TLetter::CountContainedMailers: 
  239. //----------------------------------------------------------------------------------------
  240. #pragma segment OSLDispatchRes
  241.  
  242. long TLetter::CountContainedMailers()
  243. {
  244.     long count = 0;
  245.     
  246.     if (HasAOCEToolBox())
  247.     {
  248.         WindowRef theWindowPtr = GetMailerWindowRef();
  249.         SMPMailerState theMailerState;
  250.         FailOSErr(SMPGetMailerState((WindowPtr)theWindowPtr, &theMailerState));
  251.         count = theMailerState.mailerCount;
  252.     }
  253.     
  254.     return count;
  255. }
  256.  
  257. //----------------------------------------------------------------------------------------
  258. // TLetter::DeleteMailer
  259. //----------------------------------------------------------------------------------------
  260. #pragma segment AMailerRes
  261.  
  262. void TLetter::DeleteMailer()
  263. {
  264.     if (HasMailer())
  265.     {
  266.         TAppleEvent* theEvent = new TAppleEvent;
  267.         theEvent->IAppleEvent(kAECoreSuite, kAEDelete, gServerAddress, kAEWaitReply);
  268.         
  269.         TMailer* theMailer = (TMailer *)GetIndContainedMailer(CountContainedMailers());
  270.         
  271.         CTempDesc theMailerDesc;
  272.         theMailer->MakeObjectSpecifier(theMailerDesc, formAbsolutePosition);
  273.         
  274.         theEvent->WriteParameter(keyDirectObject, theMailerDesc);
  275.         
  276.         TClientCommand* theCommand = new TClientCommand;
  277.         theCommand->IClientCommand(cAEDelete, fDocument, FALSE, FALSE, fDocument, theEvent);
  278.         fDocument->PostCommand(theCommand);
  279.     }
  280. }
  281.  
  282. //----------------------------------------------------------------------------------------
  283. // TLetter::DoAECreateMailer
  284. //----------------------------------------------------------------------------------------
  285. #pragma segment AMailerRes
  286.  
  287. void TLetter::DoAECreateMailer(TAppleEvent* message,
  288.                                TAppleEvent* reply)
  289. {
  290.     AuthIdentity    localIdentity;
  291.     OSErr            identityError;
  292.         
  293.     identityError = gMailing->GetAOCEIdentity(localIdentity, FALSE);    // no user interaction
  294.     if (identityError == kOCELocalIdentityDoesNotExist)
  295.         identityError = gMailing->GetAOCEIdentity(localIdentity, TRUE);
  296.  
  297.     if (!HasMailer() && (identityError == noErr || identityError == kOCELocalAuthenticationFail))
  298.     {
  299.         FailOSErr(SMPInitMailer(0));
  300.         
  301.         CPoint dimensions = TMailerView::GetDimensions(kExpanded);
  302.         MakeRoomForMailer(dimensions.v, kDontRedraw);
  303.         
  304.         fHasMailer = TRUE;
  305.         
  306.         TWindow* theWindow = GetMailerWindow();
  307.         
  308.         TMailerView* theMailerView = new TMailerView;
  309.         theMailerView->IMailerView(this, theWindow, kExpanded);
  310.         theMailerView->OpenNewMailer(kExpanded, kCanContract);
  311.         
  312.         if (!fLetterTabber)
  313.         {
  314.             fLetterTabber = new TLetterTabber();
  315.             fLetterTabber->ILetterTabber(TRUE, this);
  316.             theWindow->AddBehavior(fLetterTabber);
  317.         }
  318.         
  319.         dimensions.v += 100;
  320.         theWindow->SetResizeLimits(dimensions, theWindow->fResizeLimits[botRight]);
  321.         if (theWindow->Focus())
  322.             theWindow->ForceRedraw();
  323.         
  324.         TMailer* theMailer = GetIndContainedMailer(CountContainedMailers());
  325.         CTempDesc theMailerDesc;
  326.         theMailer->MakeObjectSpecifier(theMailerDesc, formAbsolutePosition);
  327.         reply->WriteParameter(keyAEResult, theMailerDesc);
  328.         
  329.         theMailer->SetPropertiesFromEvent(message);
  330.     }
  331. }
  332.  
  333. //----------------------------------------------------------------------------------------
  334. // TLetter::DoAECreateReply
  335. //----------------------------------------------------------------------------------------
  336. #pragma segment AMailerRes
  337.  
  338. void TLetter::DoAECreateReply(TAppleEvent* message,
  339.                               TAppleEvent* /*reply*/)
  340. {
  341.     if (!HasMailer())
  342.     {
  343.         CTempDesc             originalDocSpec;
  344.         MScriptableObject    *originalScriptableDoc = NULL;
  345.         TDocument            *originalDoc = NULL;
  346.         
  347.         message->ReadParameter(keyAEData, typeObjectSpecifier, originalDocSpec);
  348.         originalScriptableDoc = TOSADispatcher::fgDispatcher->ResolveObjectSpecifier(originalDocSpec);
  349.         FailNonObject(originalDoc = MA_DYNAMIC_CAST(TDocument, originalScriptableDoc));
  350.         
  351.         WindowRef     originalWindow = NULL;
  352.         MMailable    *originalMailableDoc = NULL;
  353.         
  354.         originalMailableDoc = MA_DYNAMIC_CAST(MMailable, originalDoc);
  355.         if (originalMailableDoc)
  356.         {
  357.             TLetter* originalLetter = originalMailableDoc->fLetter;
  358.             if (originalLetter)
  359.                 originalWindow = originalLetter->GetMailerWindowRef();
  360.         }
  361.         
  362.         FailOSErr(SMPInitMailer(0));
  363.         
  364.         CPoint dimensions = TMailerView::GetDimensions(kExpanded);
  365.         
  366.         MakeRoomForMailer(dimensions.v, kDontRedraw);
  367.         fHasMailer = TRUE;
  368.         
  369.         TWindow* theWindow = this->GetMailerWindow();
  370.         
  371.         TMailerView* theMailerView = new TMailerView;
  372.         theMailerView->IMailerView(this, theWindow, kExpanded);
  373.  
  374.         theMailerView->OpenReplyMailer(originalWindow, fReplyToAll, kExpanded, kCanContract);
  375.         
  376.         if (!fLetterTabber)
  377.         {
  378.             fLetterTabber = new TLetterTabber();
  379.             fLetterTabber->ILetterTabber(TRUE, this);
  380.             theWindow->AddBehavior(fLetterTabber);
  381.         }
  382.         
  383.         dimensions.v += 100;
  384.         theWindow->SetResizeLimits(dimensions, theWindow->fResizeLimits[botRight]);
  385.         
  386.         fMailDoc->SetReplyContents(originalDoc);
  387.         
  388.         if (theWindow->Focus())
  389.             theWindow->ForceRedraw();
  390.     }
  391. }
  392.  
  393. //----------------------------------------------------------------------------------------
  394. // TLetter::DoAESend
  395. //----------------------------------------------------------------------------------------
  396. #pragma segment AMailerRes
  397.  
  398. void TLetter::DoAESend(TAppleEvent* message,
  399.                        TAppleEvent* /*reply*/)
  400. {
  401.     if (HasAOCEToolBox())
  402.     {
  403.         SMPSendOptions sendOptions;
  404.         sendOptions.signWhenSent = message->ReadBoolean(keyAESignWhenSent);
  405.         
  406.         DescType thePriority = message->ReadEnum(keyAEPriority);
  407.         
  408.         switch(thePriority)
  409.         { 
  410.             case enumPriorityLow:
  411.                 sendOptions.priority = kIPMLowPriority;
  412.                 break;
  413.             
  414.             case enumPriorityHigh:
  415.                 sendOptions.priority = kIPMHighPriority;
  416.                 break;
  417.             
  418.             case enumPriorityNormal:
  419.             default:
  420.                 sendOptions.priority = kIPMNormalPriority;
  421.                 break;
  422.         };
  423.     
  424.         SMPSendFormatMask whichFormats = 0;
  425.     
  426.         CStr255 nativeName;
  427.         if (message->HasParameter(keyAEIncludeMainEnclFmt))
  428.         {
  429.             whichFormats += kSMPNativeMask;
  430.             message->ReadString(keyAEIncludeMainEnclFmt, nativeName);
  431.         }
  432.     
  433.         if (message->ReadBoolean(keyAEIncludeSnapShotFmt))
  434.             whichFormats += kSMPImageMask;
  435.         
  436.         if (message->ReadBoolean(keyAEIncludeAppleMailFmt))
  437.             whichFormats += kSMPStandardInterchangeMask;
  438.     
  439.         SendDocument((Ptr)&sendOptions, whichFormats, nativeName);
  440.     }
  441. }
  442.  
  443. //----------------------------------------------------------------------------------------
  444. // TLetter::DoForward
  445. //----------------------------------------------------------------------------------------
  446. #pragma segment AMailerRes
  447.  
  448. void TLetter::DoForward()
  449. {
  450.     // Create a new document in reply to this one.
  451.     AuthIdentity localIdentity;
  452.     
  453.     if (gMailing->GetAOCEIdentity(localIdentity, TRUE) == noErr)
  454.     {
  455.         TMailerView* itsMailerView = this->GetMailerView();
  456.         if(!itsMailerView->fMailerExpanded)
  457.             itsMailerView->ExpandMailer();
  458.         FailOSErr(SMPMailerForward((WindowPtr)GetMailerWindowRef(), localIdentity));
  459.  
  460.     }
  461. }
  462.  
  463. //----------------------------------------------------------------------------------------
  464. // TLetter::DoMailMenuCommand: 
  465. //----------------------------------------------------------------------------------------
  466. #pragma segment MASelCommand
  467.  
  468. Boolean TLetter::DoMailMenuCommand(CommandNumber aCommandNumber)
  469. {
  470.     Boolean handled = TRUE;
  471.     
  472.     switch (aCommandNumber)
  473.     {
  474.         case cAddMailer:
  475.             if (HasAOCEToolBox())
  476.             {
  477.                 if (this->HasMailer())
  478.                     this->DeleteMailer();
  479.                 else
  480.                     this->AddMailer();
  481.             }
  482.             break;
  483.  
  484.         case cSend:
  485.             if (HasAOCEToolBox() && this->ValidateForSend())
  486.                 this->DoSend();
  487.             break;
  488.  
  489.         case cReply:
  490.             if (HasAOCEToolBox())
  491.                 this->DoReply();
  492.             break;
  493.  
  494.         case cForward:
  495.             if (HasAOCEToolBox())
  496.                 this->DoForward();
  497.             break;
  498.  
  499.         default:
  500.             handled = FALSE;
  501.             break;
  502.     }
  503.     
  504.     return handled;
  505. } // TLetter::DoMailMenuCommand 
  506.  
  507. //----------------------------------------------------------------------------------------
  508. // TLetter::DoReply
  509. //----------------------------------------------------------------------------------------
  510. #pragma segment AMailerRes
  511.  
  512. void TLetter::DoReply()
  513. {
  514.     // Create a new document in reply to this one.
  515.     
  516.     CTempDesc mySpec;
  517.     fDocument->MakeObjectSpecifier(mySpec, fDocument->GetSpecifierForm());
  518.     
  519.     CTempDesc appSpec;
  520.     gDispatcher->MakeObjectSpecifier(appSpec);
  521.     
  522.     TAppleEvent* theEvent = TAppleEvent::MakeCreateElementEvent(gServerAddress, kAEWaitReply, 
  523.         appSpec, cReplyDocument, kAEBeginning, mySpec, CAEDesc::fgNullDesc);
  524.     
  525.     TClientCommand* theSendAECmd = new TClientCommand;
  526.     theSendAECmd->IClientCommand(cAECreateElement, gDispatcher, FALSE, FALSE,
  527.                                  gDispatcher, theEvent);
  528.     
  529.     gDispatcher->PostCommand(theSendAECmd);
  530. }
  531.  
  532. //----------------------------------------------------------------------------------------
  533. // TLetter::DoSend
  534. //----------------------------------------------------------------------------------------
  535. #pragma segment AMailerRes
  536.  
  537. void TLetter::DoSend()
  538. {
  539.     // Tell this document to send itself
  540.     
  541.     CStr255 nativeName;
  542.     SMPSendFormat shouldSend;
  543.     SMPSendOptions sendOptions;
  544.  
  545.     if (DoSendOptions((Ptr)&shouldSend, (Ptr)&sendOptions, nativeName))
  546.     {
  547.         TAppleEvent* theEvent = new TAppleEvent;
  548.         theEvent->IAppleEvent(kAEMailSuite, kAESendLetter, gServerAddress, kAEWaitReply);
  549.         
  550.         CTempDesc mySpecifier;
  551.         fDocument->MakeObjectSpecifier(mySpecifier, formName);
  552.         theEvent->WriteParameter(keyDirectObject, mySpecifier);
  553.         
  554.         if (shouldSend.whichFormats & kSMPImageMask)
  555.             theEvent->WriteBoolean(keyAEIncludeSnapShotFmt, TRUE);
  556.         
  557.         if (shouldSend.whichFormats & kSMPStandardInterchangeMask)
  558.             theEvent->WriteBoolean(keyAEIncludeAppleMailFmt, TRUE);
  559.         
  560.         if (shouldSend.whichFormats & kSMPNativeMask)
  561.             theEvent->WriteString(keyAEIncludeMainEnclFmt, nativeName);
  562.         
  563.         if (sendOptions.signWhenSent)
  564.             theEvent->WriteBoolean(keyAESignWhenSent, TRUE);
  565.         
  566.         DescType thePriority;
  567.         
  568.         switch(sendOptions.priority)
  569.         { 
  570.             case kIPMLowPriority:
  571.                 thePriority = enumPriorityLow;
  572.                 break;
  573.             
  574.             case kIPMHighPriority:
  575.                 thePriority = enumPriorityHigh;
  576.                 break;
  577.             
  578.             case kIPMNormalPriority:
  579.             default:
  580.                 thePriority = enumPriorityNormal;
  581.                 break;
  582.         };
  583.         
  584.         theEvent->WriteEnum(keyAEPriority, thePriority);
  585.         
  586.         // Now send it off
  587.         TClientCommand* theSendAECmd = new TClientCommand;
  588.         theSendAECmd->IClientCommand(cSend, gDispatcher, FALSE, FALSE, gDispatcher,
  589.                                      theEvent);
  590.         gDispatcher->PostCommand(theSendAECmd);
  591.     }
  592. }
  593.  
  594. //----------------------------------------------------------------------------------------
  595. // TLetter::ValidateForSend
  596. //----------------------------------------------------------------------------------------
  597. #pragma segment AMailerRes
  598.  
  599. Boolean TLetter::ValidateForSend()
  600. {
  601.     WindowRef        theWindow = GetMailerWindowRef();
  602.     SMPMailerState    theMailerState;
  603.     Boolean            canSend = TRUE;
  604.     AuthIdentity    localIdentity;
  605.     
  606.     // Get the local identity with user interaction allowed. This may 
  607.     // force the user to unlock their key chain
  608.     if (gMailing->GetAOCEIdentity(localIdentity, TRUE) == noErr)
  609.     {
  610.         FailOSErr(SMPGetMailerState((WindowPtr)theWindow, &theMailerState));
  611.         unsigned short whichMailer = theMailerState.currentMailer;
  612.       
  613.         unsigned short theSize = 0;
  614.         FailOSErr(SMPGetComponentSize((WindowPtr)theWindow, whichMailer, kSMPRegarding, &theSize));
  615.         
  616.         MAVolatileInit(Ptr, subjectBuffer, NULL);
  617.           
  618.           FailInfo fi;
  619.           Try(fi)
  620.           {
  621.               FailNIL(subjectBuffer = NewPermPtr(theSize));
  622.                 // convert the subject field to a pascal string
  623.             FailOSErr(SMPGetComponentInfo((WindowPtr)theWindow, whichMailer, kSMPRegarding, subjectBuffer));
  624.             CStr255 subjectString(OCERToPString((RString *)subjectBuffer));
  625.             subjectBuffer = DisposeIfPtr(subjectBuffer);
  626.             
  627.             if (subjectString.IsEmpty())
  628.             {
  629.                 StdAlert(phNoSubject);
  630.                 canSend = FALSE;
  631.             }
  632.             fi.Success();
  633.         }
  634.         else    // Recover
  635.         {
  636.             DisposeIfPtr(subjectBuffer);
  637.             fi.ReSignal();
  638.         }
  639.         
  640.         if (canSend)    // test the recipient list
  641.         {
  642.             unsigned short numberOfAddresses;
  643.             unsigned short nextItem;
  644.             Boolean isMoreInfo;
  645.             
  646.             FailOSErr(SMPGetListItemInfo((WindowPtr)theWindow, whichMailer ,kSMPTo ,NULL, 0 , 0, &numberOfAddresses,
  647.                 &nextItem, &isMoreInfo));
  648.             
  649.             if (numberOfAddresses < 1)
  650.             {
  651.                 StdAlert(phNoRecipient);
  652.                 canSend = FALSE;
  653.             }
  654.         }
  655.     }
  656.     else
  657.         canSend = FALSE;
  658.         
  659.     return canSend;
  660. }
  661.  
  662. //----------------------------------------------------------------------------------------
  663. // TLetter::DoSendOptions
  664. //----------------------------------------------------------------------------------------
  665. #pragma segment AMailerRes
  666.  
  667. Boolean TLetter::DoSendOptions(Ptr shouldSend,
  668.                                  Ptr sendOptions,
  669.                                  CStr255& nativeFormatName)
  670. {
  671.     CStr255 appName;
  672.     CStr255 docName;
  673.     
  674.     gDispatcher->GetApplicationName(appName);
  675.     fDocument->GetTitle(docName);
  676.     StringPtr nativeFormats[1];
  677.     nativeFormats[0] = (StringPtr) & appName;
  678.     SMPSendFormatMask canSend = fMailDoc->GetSendFormats();
  679.     SMPSendFormat currentFormat;
  680.     currentFormat.whichFormats = canSend;
  681.     currentFormat.whichNativeFormat = 0;
  682.     OSErr sendErr = SMPSendOptionsDialog((WindowPtr)GetMailerWindowRef(), docName,
  683.                                          nativeFormats, 1, canSend, ¤tFormat, NULL,
  684.                                          (long)fDocument, (SMPSendFormat*)shouldSend,
  685.                                          (SMPSendOptions*)sendOptions);
  686.     Boolean sendIt = sendErr == noErr;
  687.     if (sendIt)
  688.         nativeFormatName = (CStr255 &)*nativeFormats[((SMPSendFormat*)shouldSend)->whichNativeFormat];
  689.     return (sendIt);
  690. }
  691.  
  692. //----------------------------------------------------------------------------------------
  693. // TLetter::DoSetupMailMenus: 
  694. //----------------------------------------------------------------------------------------
  695. #pragma segment MADocumentRes
  696.  
  697. void TLetter::DoSetupMailMenus()
  698. {
  699.     if (HasAOCEToolBox())
  700.     {
  701.         Enable(cAddMailer, TRUE);
  702.         Boolean gotAMailer = this->HasMailer();
  703.         SetMenuState(cAddMailer, kAOCEStrings, kAddMailerCmdName, kRemoveMailerCmdName, gotAMailer);
  704.         if (gotAMailer)
  705.         {
  706.             SMPMailerState theMailerState;
  707.             FailOSErr(SMPGetMailerState((WindowPtr)GetMailerWindowRef(), &theMailerState));
  708.             Enable(cForward, theMailerState.hasBeenReceived);
  709.             Enable(cReply, theMailerState.hasBeenReceived);
  710.             Enable(cSend, !theMailerState.hasBeenReceived);
  711.         }
  712.     }
  713. }
  714.  
  715. //----------------------------------------------------------------------------------------
  716. // TLetter::GetDefaultTag
  717. //----------------------------------------------------------------------------------------
  718. #pragma segment AMailerRes
  719.  
  720. void TLetter::GetDefaultTag(CStr31& tagString)
  721. {
  722.     tagString.Empty();
  723. }
  724.  
  725. //----------------------------------------------------------------------------------------
  726. // TLetter::GetIndContainedMailer
  727. //----------------------------------------------------------------------------------------
  728. #pragma segment AMailerRes
  729.  
  730. TMailer* TLetter::GetIndContainedMailer(short index)
  731. {
  732.     TMailer* mailer = NULL;
  733.     
  734.     if (HasAOCEToolBox() && (index > 0) && (index <= this->CountContainedMailers()))
  735.     {
  736.         mailer = new TMailer;
  737.         mailer->IMailer(this, GetMailerWindowRef(), index);
  738.         TOSADispatcher::fgDispatcher->AddTemporaryToken(mailer);
  739.     }
  740.     
  741.     return mailer;
  742. }
  743.  
  744. //----------------------------------------------------------------------------------------
  745. // TLetter::GetMailerView
  746. //----------------------------------------------------------------------------------------
  747. #pragma segment AMailerRes
  748.  
  749. TMailerView* TLetter::GetMailerView()
  750. {
  751.     TWindow *mailerWindow = this->GetMailerWindow();
  752.     return ((TMailerView*)mailerWindow->FindSubView(kMailerViewID));
  753. }
  754.  
  755. //----------------------------------------------------------------------------------------
  756. // TLetter::GetMailerWindow
  757. //----------------------------------------------------------------------------------------
  758. #pragma segment AMailerRes
  759.  
  760. TWindow* TLetter::GetMailerWindow()
  761. {
  762.     TWindow* mailerWindow = NULL;
  763.     
  764.     if (fDocument)
  765.     {
  766.         TList* windowList = fDocument->fWindowList;
  767.         if ((windowList != NULL) && (windowList->GetSize() > 0))
  768.             mailerWindow = (TWindow *)windowList->At(1);
  769.     }
  770.     
  771.     return mailerWindow;
  772. }
  773.  
  774. //----------------------------------------------------------------------------------------
  775. // TLetter::GetMailerWindowRef
  776. //----------------------------------------------------------------------------------------
  777. #pragma segment AMailerRes
  778.  
  779. WindowRef TLetter::GetMailerWindowRef()
  780. {
  781.     TWindow* mailerWindow = GetMailerWindow();
  782.     return mailerWindow ? mailerWindow->fWMgrWindow : NULL;
  783. }
  784.  
  785. //----------------------------------------------------------------------------------------
  786. // TLetter::HasMailer
  787. //----------------------------------------------------------------------------------------
  788. #pragma segment AMailerRes
  789.  
  790. Boolean TLetter::HasMailer()
  791. {
  792.     return fHasMailer;
  793. }
  794.  
  795. //----------------------------------------------------------------------------------------
  796. // TLetter::LetterContentChanged
  797. //----------------------------------------------------------------------------------------
  798. #pragma segment AMailerRes
  799.  
  800. void TLetter::LetterContentChanged()
  801. {
  802.     if (HasMailer())
  803.     {
  804.         WindowRef aWindow = GetMailerWindowRef();
  805.         FailOSErr(SMPContentChanged((WindowPtr)aWindow));
  806.     }
  807. }
  808.  
  809. //----------------------------------------------------------------------------------------
  810. // TLetter::MakeRoomForMailer
  811. //----------------------------------------------------------------------------------------
  812. #pragma segment AMailerRes
  813.  
  814. void TLetter::MakeRoomForMailer(long amount, Boolean redraw)
  815. {
  816.     // It's usually easier to override in the mailable document,
  817.     // so we delegate the job to it. 
  818.     fMailDoc->MakeRoomForMailer(amount, redraw);
  819. }
  820.  
  821. //----------------------------------------------------------------------------------------
  822. // TLetter::OpenLetter
  823. //----------------------------------------------------------------------------------------
  824. #pragma segment AMailerRes
  825.  
  826. void TLetter::OpenLetter()
  827. {
  828.     if (HasAOCEToolBox())
  829.     {
  830.         FailNIL(fLetterDescriptor);
  831.         LetterDescriptor theSpec = **(LetterDescriptor**)fLetterDescriptor;
  832.         TWindow* mailerWindow = this->GetMailerWindow();
  833.         WindowRef theWindow = this->GetMailerWindowRef();
  834.         OSErr err = noErr;
  835.     
  836.         FailOSErr(SMPInitMailer(0));
  837.         
  838.         CPoint dimensions = TMailerView::GetDimensions(kContracted);
  839.  
  840.         this->MakeRoomForMailer(dimensions.v, kDontRedraw);
  841.         fHasMailer = TRUE;
  842.         
  843.         TMailerView* theMailerView = new TMailerView;
  844.         theMailerView->IMailerView(this, mailerWindow, kContracted);
  845.         theMailerView->OpenOldMailer(theSpec, kContracted, kCanContract);
  846.         
  847.         if (!fLetterTabber)
  848.         {
  849.             fLetterTabber = new TLetterTabber();
  850.             fLetterTabber->ILetterTabber(TRUE, this);
  851.             mailerWindow->AddBehavior(fLetterTabber);
  852.         }
  853.  
  854.         dimensions.v += 100;
  855.         mailerWindow->SetResizeLimits(dimensions, mailerWindow->fResizeLimits[botRight]);
  856.         
  857.         if (mailerWindow->Focus())
  858.             mailerWindow->ForceRedraw();
  859.     
  860.         if (!theSpec.onDisk)
  861.         {
  862.             RString name;
  863.             err = SMPGetComponentInfo((WindowPtr)theWindow, 1, kSMPRegarding, &name);
  864.             if (err == noErr)
  865.             {
  866.                 CStr255 theTitle(OCERToPString(&name));
  867.                 fDocument->SetTitle(theTitle);
  868.             }
  869.         }
  870.         
  871.         Boolean readContent;
  872.         
  873.         readContent = fMailDoc->ReadNativeMailContent();
  874.         
  875.         if (!readContent)
  876.             readContent = fMailDoc->ReadSnapshotMailContent();
  877.         
  878.         if (!readContent)
  879.             fMailDoc->ReadStandardMailContent();
  880.     }
  881. }
  882.  
  883. //----------------------------------------------------------------------------------------
  884. // TLetter::ReadLetter
  885. //----------------------------------------------------------------------------------------
  886. #pragma segment AMailerRes
  887.  
  888. void TLetter::ReadLetter(Boolean /*forPrinting*/)
  889. {
  890. }
  891.  
  892. //----------------------------------------------------------------------------------------
  893. // TLetter::ReadSnapshotMailContent
  894. //----------------------------------------------------------------------------------------
  895. #pragma segment AMailerRes
  896.  
  897. Boolean TLetter::ReadSnapshotMailContent()
  898. {
  899.     return FALSE;
  900. }
  901.  
  902. //----------------------------------------------------------------------------------------
  903. // TLetter::ReadStandardMailContent
  904. //----------------------------------------------------------------------------------------
  905. #pragma segment AMailerRes
  906.  
  907. Boolean TLetter::ReadStandardMailContent()
  908. {
  909.     return FALSE;
  910. }
  911.  
  912. //----------------------------------------------------------------------------------------
  913. // TLetter::ReadNativeMailContent
  914. //----------------------------------------------------------------------------------------
  915. #pragma segment AMailerRes
  916.  
  917. Boolean TLetter::ReadNativeMailContent()
  918. {
  919.     return FALSE;
  920. }
  921.  
  922. //----------------------------------------------------------------------------------------
  923. // TLetter::SaveLetter
  924. //----------------------------------------------------------------------------------------
  925. #pragma segment AMailerRes
  926.  
  927. void TLetter::SaveLetter(CommandNumber /*itsCommandNumber*/)
  928. {
  929.     this->SubClassResponsibility();
  930. }
  931.  
  932. //----------------------------------------------------------------------------------------
  933. // TLetter::SendDocument
  934. //----------------------------------------------------------------------------------------
  935. #pragma segment AMailerRes
  936.  
  937. void TLetter::SendDocument(Ptr theSendOptions,
  938.                            unsigned long whichFormats,
  939.                            CStr255& /*nativeFormatName*/)
  940. {
  941.     WindowRef theWindow = GetMailerWindowRef();
  942.     Boolean addContent;
  943.     OSType letterCreator;
  944.     OSType letterType;
  945.     
  946.     if (whichFormats & kSMPNativeMask != 0)
  947.     {
  948.         letterCreator = fMailDoc->fMailCreator;
  949.         letterType = fMailDoc->fMailType;
  950.     }
  951.     else
  952.     {
  953.         letterCreator = 'lap2'; 
  954.         letterType = kStandardLetterFileType;
  955.     }
  956.     
  957.     FailOSErr(MAInteractWithUser()); 
  958.     FailOSErr(SMPBeginSend((WindowPtr)theWindow,letterCreator,letterType, 
  959.                            (SMPSendOptions *)theSendOptions, &addContent));
  960.  
  961.     Boolean okToSend = TRUE;    // can't be volatile because it is passed by reference
  962.     
  963.     if (addContent)
  964.     {
  965.         FailInfo fi;
  966.         Try(fi)
  967.         {
  968.             if (whichFormats & kSMPStandardInterchangeMask)
  969.                 fMailDoc->AddStandardMailContent(okToSend);
  970.             
  971.             if (okToSend && (whichFormats & kSMPImageMask))
  972.                 fMailDoc->AddSnapshotMailContent(okToSend);
  973.             
  974.             if (okToSend && (whichFormats & kSMPNativeMask))
  975.                 fMailDoc->AddNativeMailContent(okToSend);
  976.             
  977.             fi.Success();
  978.         }
  979.         else // Recover
  980.         {
  981.             okToSend = FALSE;
  982.             // fall through to EndSend
  983.         }
  984.     }
  985.     FailOSErr(SMPEndSend((WindowPtr)theWindow, okToSend));
  986.     fHasBeenSent = TRUE;
  987. } // TLetter::SendDocument
  988.  
  989. //----------------------------------------------------------------------------------------
  990. // TLetter::SetLetterDesc
  991. //----------------------------------------------------------------------------------------
  992. #pragma segment AMailerRes
  993.  
  994. void TLetter::SetLetterDesc(Handle theDesc)
  995. {
  996.     fLetterExists = TRUE;
  997.     fLetterDescriptor = DisposeIfHandle(fLetterDescriptor);
  998.     fLetterDescriptor = theDesc;
  999.     fHasBeenSent = TRUE;
  1000. }
  1001.  
  1002. //========================================================================================
  1003. // CLASS TFileBasedLetter
  1004. //========================================================================================
  1005. #undef Inherited
  1006. #define Inherited TLetter
  1007.  
  1008. #pragma segment AOCEMailerRes
  1009. MA_DEFINE_CLASS_M1(TFileBasedLetter, Inherited);
  1010.  
  1011. //----------------------------------------------------------------------------------------
  1012. // TFileBasedLetter::TFileBasedLetter
  1013. //----------------------------------------------------------------------------------------
  1014. #pragma segment ConstructorRes
  1015.  
  1016. TFileBasedLetter::TFileBasedLetter()
  1017. {
  1018. }
  1019.  
  1020. //----------------------------------------------------------------------------------------
  1021. // TFileBasedLetter destructor
  1022. //----------------------------------------------------------------------------------------
  1023. #pragma segment MADestructorRes
  1024.  
  1025. TFileBasedLetter::~TFileBasedLetter()
  1026. {
  1027. }
  1028.  
  1029. //----------------------------------------------------------------------------------------
  1030. // TFileBasedLetter::IFileBasedLetter
  1031. //----------------------------------------------------------------------------------------
  1032. #pragma segment AMailerRes
  1033.  
  1034. void TFileBasedLetter::IFileBasedLetter(MMailable* mailDoc)
  1035. {
  1036.     ILetter(mailDoc);
  1037.     
  1038.     fFileBasedDocument = MA_DYNAMIC_CAST(TFileBasedDocument, mailDoc);
  1039.     FailNonObject(fFileBasedDocument);
  1040. }
  1041.  
  1042. //----------------------------------------------------------------------------------------
  1043. // TFileBasedLetter::AddNativeMailContent
  1044. //----------------------------------------------------------------------------------------
  1045. #pragma segment AMailerRes
  1046.  
  1047. void TFileBasedLetter::AddNativeMailContent(Boolean& /*okToSend*/) // override
  1048. {
  1049.     // Save to a temporary file then add as a main enclosure
  1050.     
  1051.     TFile* itsFile = fFileBasedDocument->GetFile();
  1052.     
  1053.     FSSpec saveFileSpec;
  1054.     itsFile->GetFileSpec(saveFileSpec);            // Save file spec since it may be clobbered 
  1055.     
  1056.     {
  1057.         CStr63 tmpName;
  1058.         fFileBasedDocument->GetTempName(tmpName);
  1059.         
  1060.         short tmpVRefNum;
  1061.         long tmpDirID;
  1062.         FailOSErr(FindFolder(saveFileSpec.vRefNum, kTemporaryFolderType, kCreateFolder,
  1063.                              &tmpVRefNum, &tmpDirID));
  1064.         FailOSErr(itsFile->SpecifyWithTrio(tmpVRefNum, tmpDirID, tmpName));
  1065.     }
  1066.     
  1067.     Boolean didExist = fFileBasedDocument->fFileExists;
  1068.     fFileBasedDocument->fFileExists = FALSE;
  1069.     fFileBasedDocument->SaveFile(cSaveCopy, FALSE, TRUE, TRUE);
  1070.     
  1071.     FailOSErr(SMPAddMainEnclosure((WindowPtr)GetMailerWindowRef(), &itsFile->fFileSpec));
  1072.     
  1073.     itsFile->DeleteFile();
  1074.     itsFile->Specify(saveFileSpec);
  1075.     fFileBasedDocument->fFileExists = didExist;
  1076. }
  1077. //----------------------------------------------------------------------------------------
  1078. // TFileBasedLetter::ReadLetter
  1079. //----------------------------------------------------------------------------------------
  1080. #pragma segment AMailerRes
  1081.  
  1082. void TFileBasedLetter::ReadLetter(Boolean /*forPrinting*/) // override
  1083. {
  1084.     LetterDescriptor theSpec;
  1085.     theSpec.onDisk = TRUE;
  1086.     
  1087.     fFileBasedDocument->GetFile()->GetFileSpec(theSpec.u.fileSpec);
  1088.     fFileBasedDocument->fFileExists = TRUE;
  1089.     
  1090.     Handle theDescHdl = NewPermHandle(sizeof(theSpec));
  1091.     **(LetterDescriptor**)theDescHdl = theSpec;
  1092.     SetLetterDesc(theDescHdl);
  1093.     
  1094.     {
  1095.         CStr63 fileName;
  1096.         fFileBasedDocument->GetFileName(fileName);
  1097.         fFileBasedDocument->SetTitle(fileName);
  1098.     }
  1099.     fFileBasedDocument->SetChangeCount(0);
  1100. }
  1101.  
  1102. //----------------------------------------------------------------------------------------
  1103. // TFileBasedLetter::ReadNativeMailContent
  1104. //----------------------------------------------------------------------------------------
  1105. #pragma segment AMailerRes
  1106.  
  1107. Boolean TFileBasedLetter::ReadNativeMailContent() // override
  1108. {
  1109.     Boolean continueRead = FALSE;
  1110.     FSSpec enclosureDir;
  1111.     
  1112.     OSErr err = SMPGetMainEnclosureFSSpec((WindowPtr)GetMailerWindowRef(), &enclosureDir);
  1113.     if (err == noErr)
  1114.     {
  1115.         MAVolatileInit(TFile*, itsFile, fFileBasedDocument->GetFile());
  1116.         FSSpec saveFileSpec;
  1117.         itsFile->GetFileSpec(saveFileSpec);        // Save file spec since it may be clobbered
  1118.         
  1119.         FailInfo fi;
  1120.         Try(fi)
  1121.         {
  1122.             itsFile->Specify(enclosureDir);
  1123.             
  1124.             Boolean forPrinting = FALSE;
  1125.             fFileBasedDocument->ReadFile(forPrinting);
  1126.             
  1127.             itsFile->Specify(saveFileSpec);
  1128.             continueRead = TRUE;
  1129.             fi.Success();
  1130.         }
  1131.         else // Recover
  1132.         {
  1133.             itsFile->Specify(saveFileSpec);
  1134.             fi.ReSignal();
  1135.         }
  1136.     }
  1137.     
  1138.     return continueRead;
  1139. }
  1140.  
  1141. //----------------------------------------------------------------------------------------
  1142. // TFileBasedLetter::SaveLetter
  1143. //----------------------------------------------------------------------------------------
  1144. #pragma segment AMailerRes
  1145.  
  1146. void TFileBasedLetter::SaveLetter(CommandNumber itsCommandNumber) // override
  1147. {
  1148.     MAVolatileInit(WindowRef, theWindow, GetMailerWindowRef());
  1149.     MAVolatileInit(TFile*, aFile, fFileBasedDocument->GetFile());
  1150.     
  1151.     FSSpec theFSSpec;
  1152.     aFile->GetFileSpec(theFSSpec);
  1153.     OSType theType = gMailing->fMainLetterFileType;    // use the letter file type
  1154.     OSType theCreator = aFile->fCreator;
  1155.     
  1156.     SMPSaveType theSaveType = kSMPSave;
  1157.     if (itsCommandNumber == cSaveAs)
  1158.         theSaveType = kSMPSaveAs;
  1159.     else if (itsCommandNumber == cSaveCopy)
  1160.         theSaveType = kSMPSaveACopy;
  1161.         
  1162.     if (fFileBasedDocument->fCommitOnSave || (itsCommandNumber != cSaveCopy))
  1163.         fFileBasedDocument->CommitLastCommand();
  1164.         
  1165.     Boolean addContent = FALSE;
  1166.     Boolean okToSend = TRUE;
  1167.     FailOSErr(SMPBeginSave((WindowPtr)theWindow, &theFSSpec, theCreator, theType, theSaveType,
  1168.                            &addContent));
  1169.     if (addContent)
  1170.     {
  1171.         FailInfo fi;
  1172.         Try(fi)
  1173.         {
  1174.             unsigned long sendFormats = fMailDoc->GetSendFormats();
  1175.             
  1176.             if (sendFormats & kSMPStandardInterchangeMask)
  1177.                 fMailDoc->AddStandardMailContent(okToSend);
  1178.             
  1179.             if (okToSend && (sendFormats & kSMPImageMask))
  1180.                 fMailDoc->AddSnapshotMailContent(okToSend);
  1181.             
  1182.             if (okToSend && (sendFormats & kSMPNativeMask))
  1183.                 fMailDoc->AddNativeMailContent(okToSend);
  1184.             
  1185.             fi.Success();
  1186.         }
  1187.         else // Recover
  1188.         {
  1189.             okToSend = FALSE;
  1190.             // fall through to EndSend
  1191.         }
  1192.     }
  1193.     FailOSErr(SMPEndSave((WindowPtr)theWindow, okToSend));
  1194.     
  1195.     fFileBasedDocument->fFileExists = TRUE;
  1196.     CStr63 name;
  1197.     aFile->GetName((CStr63 &)name);
  1198.     
  1199.     if (fFileBasedDocument->FileChanged(TRUE) == errFTypeChanged)
  1200.         fFileBasedDocument->fFile->GetFileType(fFileBasedDocument->fFile->fFileType);
  1201.     
  1202.     fFileBasedDocument->FileHasBeenSaved(name);
  1203. }// TFileBasedLetter::SaveLetter
  1204.  
  1205. //========================================================================================
  1206. // CLASS TMailer
  1207. //========================================================================================
  1208. #undef Inherited
  1209. #define Inherited TObject
  1210.  
  1211. #pragma segment AOCEMailerRes
  1212. MA_DEFINE_CLASS_M2(TMailer, Inherited, MScriptableObject);
  1213.  
  1214. //----------------------------------------------------------------------------------------
  1215. // TMailer::TMailer
  1216. //----------------------------------------------------------------------------------------
  1217. #pragma segment ConstructorRes
  1218.  
  1219. TMailer::TMailer() 
  1220.     : MScriptableObject(cMailer),
  1221.       fWindow(NULL),
  1222.       fDocument(NULL),
  1223.       fLetter(NULL)
  1224. {
  1225. }
  1226.  
  1227. //----------------------------------------------------------------------------------------
  1228. // TMailer destructor
  1229. //----------------------------------------------------------------------------------------
  1230. #pragma segment MADestructorRes
  1231.  
  1232. TMailer::~TMailer()
  1233. {
  1234. }
  1235.  
  1236. //----------------------------------------------------------------------------------------
  1237. // TMailer::IMailer
  1238. //----------------------------------------------------------------------------------------
  1239. #pragma segment AMailerRes
  1240.  
  1241. void TMailer::IMailer(TLetter* letter,
  1242.                       WindowRef theWindow,
  1243.                       short whichMailer)
  1244. {
  1245.     IObject();
  1246.     
  1247.     fWhichMailer = whichMailer;
  1248.     fWindow = theWindow;
  1249.     fLetter = letter;
  1250.     fDocument = letter->fDocument;
  1251. }
  1252.  
  1253. //----------------------------------------------------------------------------------------
  1254. // TMailer::TopMailer
  1255. //----------------------------------------------------------------------------------------
  1256. #pragma segment AMailerRes
  1257.  
  1258. Boolean TMailer::TopMailer()
  1259. {
  1260.     WindowRef theWindowPtr = fWindow;
  1261.     SMPMailerState theMailerState;
  1262.     FailOSErr(SMPGetMailerState((WindowPtr)theWindowPtr, &theMailerState));
  1263.     return theMailerState.mailerCount == fWhichMailer;
  1264. }
  1265.  
  1266. //----------------------------------------------------------------------------------------
  1267. // TMailer::GetObjectsContainer
  1268. //----------------------------------------------------------------------------------------
  1269. #pragma segment AMailerRes
  1270.  
  1271. MScriptableObject* TMailer::GetObjectsContainer()
  1272. {
  1273.     return fDocument;
  1274. }
  1275.  
  1276. //----------------------------------------------------------------------------------------
  1277. // TMailer::GetObjectProperty
  1278. //----------------------------------------------------------------------------------------
  1279. #pragma segment AMailerRes
  1280.  
  1281. Boolean TMailer::GetObjectProperty(CAEDesc& thePropertyValue,
  1282.                                    DescType whichProperty,
  1283.                                    const CAEDesc& desiredType)
  1284. {
  1285.     Boolean hasProperty = TRUE;
  1286.     FailInfo fi;
  1287.     Try(fi)
  1288.     {
  1289.         // Return properties for the mailer.
  1290.         WindowRef theWindowPtr = fWindow;
  1291.         SMPMailerState theMailerState;
  1292.         FailOSErr(SMPGetMailerState((WindowPtr)theWindowPtr, &theMailerState));
  1293.         switch (whichProperty)
  1294.         {
  1295.             case pContents:
  1296.                 {
  1297.                     thePropertyValue.CreateRecord();
  1298.                     CTempDesc theSubjectDesc;
  1299.                     this->GetObjectProperty(theSubjectDesc, pSubject, desiredType);
  1300.                     thePropertyValue.PutKeyDesc(pSubject, theSubjectDesc);
  1301.                     thePropertyValue.PutKeyBoolean(pReceived, theMailerState.hasBeenReceived);
  1302.                 }
  1303.                 break;
  1304.     
  1305.             case pName:
  1306.             case pSubject:
  1307.                 {
  1308.                     unsigned short theSize = 0;
  1309.                     FailOSErr(SMPGetComponentSize((WindowPtr)fWindow, fWhichMailer, kSMPRegarding, &theSize));
  1310.                     
  1311.                     MAVolatileInit(Ptr, buffer, NULL);
  1312.                     FailInfo fi2;
  1313.                     Try(fi2)
  1314.                     {
  1315.                         buffer = NewPtr(theSize);
  1316.                         FailOSErr(SMPGetComponentInfo((WindowPtr)fWindow, fWhichMailer, kSMPRegarding, buffer));
  1317.                         CStr255 theString(OCERToPString((RString *)buffer));
  1318.                         buffer = DisposeIfPtr(buffer);
  1319.                         thePropertyValue.PutString(theString);
  1320.                         fi2.Success();
  1321.                     }
  1322.                     else // Recover
  1323.                     {
  1324.                         buffer = DisposeIfPtr(buffer);
  1325.                         fi.ReSignal();
  1326.                     }
  1327.                 }
  1328.                 break;
  1329.     
  1330.             case pReceived:
  1331.                 {
  1332.                     thePropertyValue.PutBoolean(theMailerState.hasBeenReceived);
  1333.                 }
  1334.                 break;
  1335.     
  1336.             case pIndex:
  1337.                 {
  1338.                     thePropertyValue.PutLong(fWhichMailer);
  1339.                 }
  1340.                 break;
  1341.     
  1342.             default:
  1343.                 hasProperty = MScriptableObject::GetObjectProperty(thePropertyValue, whichProperty, desiredType);
  1344.                 break;
  1345.         }
  1346.         fi.Success();
  1347.     }
  1348.     else // Recover
  1349.     {
  1350.         hasProperty = FALSE;
  1351.     }
  1352.     return hasProperty;
  1353. }
  1354.  
  1355. //----------------------------------------------------------------------------------------
  1356. // TMailer::SetObjectProperty
  1357. //----------------------------------------------------------------------------------------
  1358. #pragma segment AMailerRes
  1359.  
  1360. void TMailer::SetObjectProperty(const CAEDesc& thePropertyValue,
  1361.                                 DescType whichProperty)
  1362. {
  1363.     // Set properties for the mailer.
  1364.     Boolean isTopMailer = this->TopMailer();
  1365.     switch (whichProperty)
  1366.     {
  1367.  
  1368.         case pContents:
  1369.             {
  1370.                 CStr255 subjectStr;
  1371.                 if (isTopMailer && thePropertyValue.GetKeyString(pSubject, subjectStr))
  1372.                 {
  1373.                     RString theSubRString;
  1374.                     OCEPToRString(subjectStr, smRoman, &theSubRString, kRStringMaxBytes);
  1375.                     SMPSetSubject((WindowPtr)fWindow, &theSubRString);
  1376.                 }
  1377.             }
  1378.             break;
  1379.  
  1380.         case pName:
  1381.         case pSubject:
  1382.             if (isTopMailer)
  1383.             {
  1384.                 CStr255 subjectStr;
  1385.                 RString theSubRString;
  1386.                 thePropertyValue.GetString(subjectStr);
  1387.                 OCEPToRString(subjectStr, smRoman, &theSubRString, kRStringMaxBytes);
  1388.                 SMPSetSubject((WindowPtr)fWindow, &theSubRString);
  1389.             }
  1390.             break;
  1391.  
  1392.         case pReceived:
  1393.             FailOSErr(errAECantSetReadOnly);
  1394.             break;
  1395.  
  1396.         default:
  1397.             MScriptableObject::SetObjectProperty(thePropertyValue, whichProperty);
  1398.             break;
  1399.     }
  1400. }
  1401.  
  1402. //----------------------------------------------------------------------------------------
  1403. // TMailer::CountContainedObjects
  1404. //----------------------------------------------------------------------------------------
  1405. #pragma segment AMailerRes
  1406.  
  1407. long TMailer::CountContainedObjects(DescType desiredType)
  1408. {
  1409.     if ((desiredType == cFile) || (desiredType == cRecipient))
  1410.     {
  1411.         SMPMailerComponent whichField = kSMPAttachments;
  1412.         if (desiredType == cRecipient)
  1413.             whichField = kSMPTo;
  1414.         unsigned short theSize = 0;
  1415.         FailOSErr(SMPGetComponentSize((WindowPtr)fWindow, fWhichMailer, whichField, &theSize));
  1416.         Ptr buffer = NewPtr(theSize);
  1417.         unsigned short startItem = 0;
  1418.         unsigned short itemCount = 0;
  1419.         unsigned short nextItem = 0;
  1420.         Boolean moreItems = FALSE;
  1421.         FailOSErr(SMPGetListItemInfo((WindowPtr)fWindow, fWhichMailer, whichField, buffer, theSize, startItem, &itemCount, &nextItem, &moreItems));
  1422.         DisposePtr(buffer);
  1423.         return itemCount;
  1424.     }
  1425.     else
  1426.         return MScriptableObject::CountContainedObjects(desiredType);
  1427. }
  1428.  
  1429. //----------------------------------------------------------------------------------------
  1430. // TMailer::DoAEDelete
  1431. //----------------------------------------------------------------------------------------
  1432. #pragma segment AMailerRes
  1433.  
  1434. void TMailer::DoAEDelete(TAppleEvent* /* message */,
  1435.                          TAppleEvent* /* reply */)
  1436. {
  1437.     if (this->TopMailer())
  1438.     {
  1439.         TWindow * mailerWindow = fLetter->GetMailerWindow();
  1440.         SMPCloseOptions closeOptionsRec;
  1441.         BlockSet((Ptr) & closeOptionsRec, sizeof(SMPCloseOptions), 0);
  1442.         FailOSErr(SMPPrepareToClose((WindowPtr)fWindow)); //user may wish to extend this to
  1443.                                                          //post dialog. See IM:AOCE App Interfaces
  1444.                                                          //page 3-59
  1445.         FailOSErr(SMPDisposeMailer((WindowPtr)fWindow, &closeOptionsRec));
  1446.         fLetter->fHasMailer = FALSE;
  1447.         
  1448.         if (fLetter->fLetterTabber)
  1449.         {
  1450.             mailerWindow->RemoveBehavior(fLetter->fLetterTabber);
  1451.             fLetter->fLetterTabber = (TLetterTabber*)FreeIfObject(fLetter->fLetterTabber);
  1452.         }
  1453.  
  1454.         TView * theMailerView = fLetter->GetMailerView();
  1455.         mailerWindow->RemoveSubView(theMailerView);
  1456.         fLetter->MakeRoomForMailer(-theMailerView->fSize.v, kRedraw);
  1457.         FreeIfObject(theMailerView);
  1458.     }
  1459. }
  1460.  
  1461. //----------------------------------------------------------------------------------------
  1462. // TMailer::GetIndContainedObject
  1463. //----------------------------------------------------------------------------------------
  1464. #pragma segment AMailerRes
  1465.  
  1466. MScriptableObject* TMailer::GetIndContainedObject(DescType desiredType,
  1467.                                                   long index)
  1468. {
  1469.     if ((desiredType == cRecipient) && (index > 0) && (index <= this->CountContainedObjects(cRecipient)))
  1470.     {
  1471.         TRecipient * theRecipient = new TRecipient;
  1472.         theRecipient->IRecipient(this, index, fWindow);
  1473.         return theRecipient;
  1474.     }
  1475.     else
  1476.         return MScriptableObject::GetIndContainedObject(desiredType, index);
  1477. }
  1478.  
  1479. //----------------------------------------------------------------------------------------
  1480. // StringToAddress
  1481. //----------------------------------------------------------------------------------------
  1482. #pragma segment AMailerRes
  1483.  
  1484. OCEPackedRecipient* StringToAddress(const CStr255& addressStr)
  1485. {
  1486.     CStr255 theStr = addressStr;
  1487.     DSSpec theDSSpec;
  1488.     BlockSet((Ptr) & theDSSpec, sizeof(theDSSpec), 0);
  1489.     RecordID rid;
  1490.     BlockSet((Ptr) & rid, sizeof(rid), 0);
  1491.     PackedRLI thePackedRLI;
  1492.     BlockSet((Ptr) & thePackedRLI, sizeof(thePackedRLI), 0);
  1493.     rid.rli = &thePackedRLI;
  1494.  
  1495.     short xSize = 0;
  1496.  
  1497.     short endOfMacName = theStr.Pos("@", 1);
  1498.     if (endOfMacName == 0)
  1499.         endOfMacName = theStr.Length() + 1;
  1500.     CStr32 machineName = theStr.Copy(1, endOfMacName - 1);
  1501.     CStr32 socketType = "MsgReceiver";
  1502.     CStr32 zoneName = "*";
  1503.     if (endOfMacName < theStr.Length())
  1504.         zoneName = theStr.Copy((endOfMacName + 1), theStr.Length() - endOfMacName);
  1505.     CStr255 typeName = "aoce Attribute Valuealanaoce mailslots";
  1506.  
  1507.     xSize = machineName.Length() + socketType.Length() + zoneName.Length() + 3;
  1508.     Ptr theExtension = NewPtrClear(xSize);
  1509.     Ptr xPtr = theExtension;
  1510.     long theLen = machineName.Length() + 1;
  1511.     MABlockMove((Ptr) & machineName, xPtr, theLen);
  1512.     xPtr += theLen;
  1513.     theLen = socketType.Length() + 1;
  1514.     MABlockMove((Ptr) & socketType, xPtr, theLen);
  1515.     xPtr += theLen;
  1516.     theLen = zoneName.Length() + 1;
  1517.     MABlockMove((Ptr) & zoneName, xPtr, theLen);
  1518.  
  1519.     RString theRecordName;
  1520.     RString theRecordType;
  1521.  
  1522.     theDSSpec.entitySpecifier = &rid;
  1523.     theDSSpec.extensionType = 'alan';
  1524.     theDSSpec.extensionSize = xSize;
  1525.     theDSSpec.extensionValue = theExtension;
  1526.  
  1527.     OCEPToRString(machineName, smRoman, &theRecordName, kRStringMaxBytes);
  1528.     rid.local.recordName = &theRecordName;
  1529.     OCEPToRString(typeName, smRoman, &theRecordType, kRStringMaxBytes);
  1530.     rid.local.recordType = &theRecordType;
  1531.  
  1532.     unsigned short theSpecSize = OCEPackedDSSpecSize(&theDSSpec);
  1533.     OCEPackedRecipient * theResult = (OCEPackedRecipient *)NewPtr(theSpecSize);
  1534.     FailOSErr(OCEPackDSSpec(&theDSSpec, (PackedDSSpec *)theResult, theSpecSize));
  1535.     DisposePtr(theExtension);
  1536.     return theResult;
  1537. }// StringToAddress
  1538.  
  1539. //========================================================================================
  1540. // CLASS TRecipient
  1541. //========================================================================================
  1542. #undef Inherited
  1543. #define Inherited TObject
  1544.  
  1545. #pragma segment AOCERes
  1546. MA_DEFINE_CLASS_M2(TRecipient, Inherited, MScriptableObject);
  1547.  
  1548. //----------------------------------------------------------------------------------------
  1549. // TRecipient::TRecipient
  1550. //----------------------------------------------------------------------------------------
  1551. #pragma segment ConstructorRes
  1552.  
  1553. TRecipient::TRecipient() 
  1554.     : MScriptableObject(cRecipient),
  1555.       fWindow(NULL),
  1556.       fMailer(NULL)
  1557. {
  1558. }
  1559.  
  1560. //----------------------------------------------------------------------------------------
  1561. // TRecipient destructor
  1562. //----------------------------------------------------------------------------------------
  1563. #pragma segment MADestructorRes
  1564.  
  1565. TRecipient::~TRecipient()
  1566. {
  1567. }
  1568.  
  1569. //----------------------------------------------------------------------------------------
  1570. // TRecipient::IRecipient
  1571. //----------------------------------------------------------------------------------------
  1572. #pragma segment AMailerRes
  1573.  
  1574. void TRecipient::IRecipient(TMailer* theMailer,
  1575.                             long index,
  1576.                             WindowRef theWindow)
  1577. {
  1578.     IObject();
  1579.     fWindow = theWindow;
  1580.     fMailer = theMailer;
  1581.     fWhichRecipient = index;
  1582. }
  1583.  
  1584. //----------------------------------------------------------------------------------------
  1585. // TRecipient::GetObjectsContainer
  1586. //----------------------------------------------------------------------------------------
  1587. #pragma segment AMailerRes
  1588.  
  1589. MScriptableObject* TRecipient::GetObjectsContainer()
  1590. {
  1591.     return fMailer;
  1592. }
  1593.  
  1594. //----------------------------------------------------------------------------------------
  1595. // TRecipient::GetObjectProperty
  1596. //----------------------------------------------------------------------------------------
  1597. #pragma segment AMailerRes
  1598.  
  1599. Boolean TRecipient::GetObjectProperty(CAEDesc& thePropertyValue,
  1600.                                        DescType whichProperty,
  1601.                                      const CAEDesc& desiredType)
  1602. {
  1603.     MAVolatileInit(Ptr, buffer, NULL);
  1604.     Boolean hasProperty = TRUE;
  1605.  
  1606.     FailInfo fi;
  1607.     Try(fi)
  1608.     {
  1609.         if (whichProperty == pName || whichProperty == pMailAddress || whichProperty == pRecipientType)
  1610.         {
  1611.             SMPMailerComponent whichField = kSMPTo;
  1612.             unsigned short theSize = kOCEPackedRecipientMaxBytes;
  1613.             FailNIL(buffer = NewPermPtr(theSize));
  1614.             unsigned short startItem = fWhichRecipient - 1;
  1615.             unsigned short itemCount = 0;
  1616.             unsigned short nextItem = 0;
  1617.             Boolean moreItems = FALSE;
  1618.             FailOSErr(SMPGetListItemInfo(fMailer->fWindow, fMailer->fWhichMailer, whichField, buffer, 
  1619.                 theSize, startItem, &itemCount, &nextItem, &moreItems));
  1620.             
  1621.             if (itemCount > 0)
  1622.             {
  1623.                 switch (whichProperty)
  1624.                 {
  1625.                     case pRecipientType:
  1626.                         {
  1627.                             DescType theRecipientType;
  1628.                             short recipientTypeID = *(short *)buffer;
  1629.                             
  1630.                             if (recipientTypeID == kSMPCCAddress)
  1631.                                 theRecipientType = kAECCRecipient;
  1632.                             else if (recipientTypeID == kSMPBCCAddress)
  1633.                                 theRecipientType = kAEBCCRecipient;
  1634.                             else if (recipientTypeID == kSMPToAddress)
  1635.                                 theRecipientType = kAEToRecipient;
  1636.                             else
  1637.                                 FailOSErr(paramErr);
  1638.                             
  1639.                             thePropertyValue.PutEnum(theRecipientType);
  1640.                         }
  1641.                         break;
  1642.                     
  1643.                     case pName:
  1644.                         {
  1645.                             PackedDSSpecPtr theDSPtr = PackedDSSpecPtr(buffer + sizeof(short));
  1646.                             CDSSpec aDSSpec(theDSPtr);
  1647.                             thePropertyValue.PutString(aDSSpec.GetRecordName());
  1648.                         }
  1649.                         break;
  1650.                     
  1651.                     case pMailAddress:
  1652.                         {
  1653.                             PackedDSSpec* theDSPtr = (PackedDSSpec *)(buffer + sizeof(short));
  1654.                             CTempDesc theDSSpecDesc;
  1655.                             FailOSErr(AECreateDesc(typePackedDSSpec, buffer + sizeof(short), sizeof(ProtoPackedDSSpec) + theDSPtr->dataLength , theDSSpecDesc));
  1656.                             DescType typeWanted = typeChar;
  1657.                             if (desiredType.GetDataHandle())
  1658.                                 typeWanted = desiredType.GetType();
  1659.                             FailOSErr(AECoerceDesc(theDSSpecDesc, typeWanted, thePropertyValue));
  1660.                         }
  1661.                         break;
  1662.                         
  1663.                     default:
  1664.                         break;    // will never get here
  1665.                 }
  1666.             }
  1667.             else
  1668.                 FailOSErr(errAENoSuchObject);
  1669.         }
  1670.         else
  1671.             hasProperty = MScriptableObject::GetObjectProperty(thePropertyValue, whichProperty, desiredType);
  1672.         fi.Success();
  1673.     }
  1674.     else    // recover
  1675.     {
  1676.         DisposeIfPtr(buffer);
  1677.         fi.ReSignal();
  1678.     }
  1679.     
  1680.     DisposeIfPtr(buffer);
  1681.     return hasProperty;
  1682. }
  1683.  
  1684. //----------------------------------------------------------------------------------------
  1685. // TRecipient::SetObjectProperty
  1686. //----------------------------------------------------------------------------------------
  1687. #pragma segment AMailerRes
  1688.  
  1689. void TRecipient::SetObjectProperty(const CAEDesc& thePropertyValue,
  1690.                                    DescType whichProperty)
  1691. {
  1692.     switch (whichProperty)
  1693.     {
  1694.         case pName:
  1695.         case pMailAddress:
  1696.         case pRecipientType:
  1697.             FailOSErr(errAECantSetReadOnly);
  1698.             break;
  1699.  
  1700.         default:
  1701.             MScriptableObject::SetObjectProperty(thePropertyValue, whichProperty);
  1702.             break;
  1703.     }
  1704. }
  1705.  
  1706. #endif // qPowerTalk
  1707.  
  1708. //----------------------------------------------------------------------------------------
  1709. // End of UMailer.cp
  1710.  
  1711. #pragma segment Inline
  1712.